/*
    This file is part of Slydini.

    Slydini is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Slydini is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Slydini.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <QtGui>
#include <math.h>
#include "SWidget.h"
#include "../configuration/configuration.h"
#include "../tinyxml/tinyxml.h"

SWidget::Pen SWidget::penStyle;
QColor SWidget::color;
int SWidget::penSize;
int SWidget::penWidth;
int SWidget::step;
int SWidget::menu;
int SWidget::imageNo;

bool fromMenu = false;

SWidget::SWidget(int a, int b, QWidget *parent) : QWidget(parent)
{
    this-> forpen1a = new QImage(200,200, QImage::Format_ARGB32);
    this-> forpen1b = new QImage(200,200, QImage::Format_ARGB32);
    this-> forpen1c = new QImage(200,200, QImage::Format_ARGB32);
    this->forpen1a->load("painting/img/1a.png");
    this->forpen1b->load("painting/img/1b.png");
    this->forpen1c->load("painting/img/1c.png");
    this-> forpen2a = new QImage(200,200, QImage::Format_ARGB32);
    this-> forpen2b = new QImage(200,200, QImage::Format_ARGB32);
    this-> forpen2c = new QImage(200,200, QImage::Format_ARGB32);
    this->forpen2a->load("painting/img/2a.png");
    this->forpen2b->load("painting/img/2b.png");
    this->forpen2c->load("painting/img/2c.png");
    this-> forpen3a = new QImage(200,200, QImage::Format_ARGB32);
    this-> forpen3b = new QImage(200,200, QImage::Format_ARGB32);
    this-> forpen3c = new QImage(200,200, QImage::Format_ARGB32);
    this->forpen3a->load("painting/img/3a.png");
    this->forpen3b->load("painting/img/3b.png");
    this->forpen3c->load("painting/img/3c.png");
	this->image=new QImage(a,b, QImage::Format_ARGB32);
//    this->forpen1a->load("img/1a.png");
//    *image = this->forpen1a->scaled(200,200,Qt::KeepAspectRatio);
    line = false;
    this->sPoint=new QPoint(0,0);
    this->setMouseTracking(true);
    this->firstPoint = new QPoint(0,0);
    this->lmenu = new LeftMenu();
    this->umenu= new UpMenu();
    this->rmenu= new RightMenu();
    this->dmenu= new DownMenu();

    color = Qt::red;
    penWidth = 4;
    step = 3;
    penStyle = images;
    penSize  = 19;
    menu = 0;
    imageNo = 3;
	
    srand( (unsigned) time(NULL));
    
    

}

//------------------------
SWidget::~SWidget()
{
    delete image;
    image = NULL;
}
//------------------------
void SWidget::paintEvent(QPaintEvent*)
{
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing, true);
    p.drawImage(QPoint(0,0), *image);
}
//------------------------
void SWidget:: mouseMoveEvent(QMouseEvent* event)
{

    if ( menu == 0 && !line){
         Configuration *c = Configuration::getConfiguration("configuration.xml"); 
         if (event->pos().x() < 30 && menu == 0 ){        	
            lmenu->show();            
            menu = 1;                   
         }
         if (event->pos().y() < 30 && menu == 0){            
            umenu->show(); 
            menu = 2;                    
         }
         if (event->pos().x() > c->queryInt("desktop/width")-30 && menu == 0){           
            rmenu->show();
            menu = 3;                    
         }
         
         if (event->pos().y() > c->queryInt("desktop/height")-30 && menu == 0){          
            dmenu->show();
            menu = 4;                    
         }
    }

    if (line) {
    	QPoint P = event->pos() - *sPoint;
        if (P.manhattanLength() > step ) {
            drawLineTo(event->pos());
            *sPoint = event->pos();
        }   
    }

}
//------------------------
void SWidget::mousePressEvent(QMouseEvent *event)
{
    if (menu == 0) {
        if (event->button() == Qt::LeftButton) {
            *sPoint = event->pos();
            *firstPoint = event->pos();
            if ( penStyle != images ) {
                line = true;
            }
         }
        if (event->button() == Qt::RightButton) {
            clear();    
        }
    }
    else { 
    
     if (menu == 1) {
              lmenu->hide();
              menu = 0;
     }
     if (menu == 2) {
              umenu->hide();
              menu = 0;
     }
     if (menu == 3) {
              rmenu->hide();
              menu = 0;
     }
     if (menu == 4) {
              dmenu->hide();
              menu = 0;
     }
     fromMenu = true;
    }

}
//-------------------------------------------------
void SWidget::mouseReleaseEvent(QMouseEvent *event)
{
   if (!fromMenu && event->button() ==  Qt::LeftButton) { 
        *sPoint = event->pos();
        drawSPoint(*sPoint); 
        line = false;
   }
   if (fromMenu) {
        fromMenu = false;
    }
}
//-------------------------------------------------
void SWidget::clear() {

    int a, b;
    a = image->width();
    b = image->height();
    delete image;
    image = NULL;
	this->image=new QImage(a,b, QImage::Format_ARGB32);
    update();
    
}

//-------------------------------------------------
void SWidget::drawSPoint(const QPoint &pnt)
{
    QPainter p(image);
    p.setPen(QPen(color, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    switch (penStyle) {
        case circles: {
                p.drawEllipse(pnt,penSize*2,penSize*2);
        }
            break;
        case spray: {
            p.drawPoint(pnt);
            int ilPkt = 4; // punktow w cwiartce
            int ix, iy;
            for (int i=0; i<4; i++) {
                switch(i){
                    case 0:  {ix = -1; iy = -1;} break;
                    case 1:  {ix = -1; iy =  1;} break;
                    case 2:  {ix =  1; iy =  1;} break;
                    default: {ix =  1; iy = -1;} break;
                }
                for (int j = 0; j<ilPkt; j++) {
                    int r1 = rand()%(penSize) + 1;
                    int m2 = (int)(sqrt((float)(penSize*penSize-r1*r1)) + 1);
                    int r2 = rand()%(m2) + 1;
                    QPoint tmp(pnt.x() + ix*r1, pnt.y() + iy*r2);
                    p.drawPoint(tmp);
                }
            }
        }
            break;
        case symetric: {
            p.drawPoint(pnt);
            int x = abs(this->firstPoint->x() - pnt.x());
            if (pnt.x() < this->firstPoint->x())
                x += this->firstPoint->x();
            else
                x = this->firstPoint->x() - x;
            
            QPoint tmp(x, pnt.y());
            p.drawPoint(tmp);
            
        }
            break;
        case ribbon1: {
            QPoint tmp((int)(pnt.x() - penSize/2.0), (int)(pnt.y() - penSize/2.0));
            QPoint tmp2((int)(pnt.x() + penSize/2.0), (int)(pnt.y() + penSize/2.0));
            p.drawLine(tmp, tmp2);
        }
            break;
        case ribbon2: {
            QPoint tmp((int)(pnt.x() - penSize/2.0), (int)(pnt.y() + penSize/2.0));
            QPoint tmp2((int)(pnt.x() + penSize/2.0), (int)(pnt.y() - penSize/2.0));
            p.drawLine(tmp, tmp2);
        }
            break;
        case images: {
                int s[3][2];    // height (0) and width (1) of 3 images
                QImage *i[3];   // images to draw
                int k = rand()%3;
                if (imageNo == 1) {
                    i[k%3] = forpen1a;
                    i[(k+1)%3] = forpen1b;
                    i[(k+2)%3] = forpen1c;
                }
                else if (imageNo == 3 ) {
                    i[k%3] = forpen3a;
                    i[(k+1)%3] = forpen3b;
                    i[(k+2)%3] = forpen3c;
                }
                else {
                    i[k%3] = forpen2a;
                    i[(k+1)%3] = forpen2b;
                    i[(k+2)%3] = forpen2c;
                }

                for (int j = 0; j<3; j++) { 
                    s[j][0] = i[j]->height();
                    s[j][1] = i[j]->width();
                }
                int xx = s[0][0]/2+s[1][0]/2;
                int yy = s[0][1]/2+s[1][1]/2;
                int xxx = xx+s[2][0]/2;
                int yyy = yy+s[2][1]/2;

                QPoint P = pnt - *firstPoint;
                
                printf("P %d %d\n",P.x(),P.y());
                printf("hw %d %d - %d %d - %d %d\n", s[0][0], s[0][1], s[1][0], s[1][1], s[2][0], s[2][1]);
                QPoint tmp  ((pnt.x() - s[0][0]/2), (pnt.y() - s[0][1]/2));
                QPoint tmp2 ((firstPoint->x() - s[1][0]/2), (firstPoint->y() - s[1][1]/2));
                QPoint tmp3 ((firstPoint->x() + P.x()/2 - s[2][0]/2), (firstPoint->y() + P.y()/2 - s[2][1]/2));
    
                printf("xxyy %d %d\n",xx,yy);
                if ( abs(P.x()) > xx || abs(P.y()) > yy ) {
                        printf("probuje rysować");
                        p.drawImage(tmp2, *i[1]);                
                }
                if ( abs(P.x()) > xxx || abs(P.y()) > yyy ) {
                        p.drawImage(tmp3, *i[2]);                
                }

                p.drawImage(tmp, *i[0]);
        }
            break;
        default: {
            p.drawPoint(pnt);
        }
            break;
    
    }
    update();
}
//-------------------------------------------------
void SWidget::drawLineTo(const QPoint &pnt) 
{
    drawMyLine(*sPoint, pnt);
}
//-------------------------------------------------
void SWidget::drawMyLine(const QPoint &pnt1, const QPoint &pnt2)
{
    QPoint tmp = pnt2 - pnt1;
    int len = tmp.manhattanLength();
    QPoint stepPoint(0,0);
    for (int i = 0; (pnt2 - (stepPoint + pnt1)).manhattanLength() > step ; i+=step) {
        drawSPoint(pnt1 + stepPoint);
        stepPoint = i*tmp/(float)len;
    }
}
